/**
 * %W% %E%
 *
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 * Use and Distribution is subject to the Java Research License available
 * at <http://wwws.sun.com/software/communitysource/jrl.html>.
 */

package com.sun.source.util;

import com.sun.source.tree.*;

/** 
 * A TreeVisitor that visits all the child tree nodes, and provides
 * support for maintaining a path for the parent nodes.
 * To visit nodes of a particular type, just override the 
 * corresponding visitorXYZ method.
 * Inside your method, call super.visitXYZ to visit descendant
 * nodes.
 * 
 * @author Jonathan Gibbons
 * @since 1.6
 */
public class TreePathScanner<R, P> extends TreeScanner<R, P> {
    
    /**
     * Scan a tree from a position identified by a TreePath.
     */
    public R scan(TreePath path, P p) {
	this.path = path;
	try {
	    return path.getLeaf().accept(this, p);
	} finally {
	    this.path = null;
	}
    }
    
    /**
     * Scan a single node. 
     * The current path is updated for the duration of the scan.
     */	
    @Override
    public R scan(Tree tree, P p) {
	if (tree == null)
	    return null;
	
        TreePath prev = path;
        path = new TreePath(path, tree);      
	try {
	    return tree.accept(this, p);
	} finally {
	    path = prev;
	}
    }
    
    /**
     * Get the current path for the node, as built up by the currently
     * active set of scan calls.
     */
    public TreePath getCurrentPath() {
	return path;
    }
    
    private TreePath path;
}
